package minsat;

/**
 * A propositional variable indicated by its name and whether or not it is negated. Non-negated
 * literals are of the form "x" while negated variables are of the form "!x"
 */
public class Literal implements Comparable<Literal>
{
  public final String name;
  public boolean neg;

  /**
   * Builds a literal with given name and negation
   * 
   * @param name
   *          Literal's name
   * @param neg
   *          True is literal if negated, ie. of the form "!x"
   */
  public Literal(String name, boolean neg)
  {
    this.name = name;
    this.neg = neg;
  }

  /**
   * Copy constructor for Literal
   */
  public Literal(Literal l)
  {
    this.name = l.name;
    this.neg = l.neg;
  }

  public String toString()
  {
    String result = "";
    if (neg) result += "!";
    result += name;
    return result;
  }

  @Override
  public int compareTo(Literal literal)
  {
    if (!name.equals(literal.name))
      return 1; // different literals
    else if (neg == literal.neg)
      return 0; // identical literals
    else
      return -1;  // opposite literals
  }

  /**
   * Returns this literal in a non-negated form
   */
  public Literal nonNegated()
  {
    if (!neg)
      return this;
    else
      return new Literal(name, false);
  }

  /**
   * Returns this literal in a negated form
   */
  public Literal negated()
  {
    if (neg)
      return this;
    else
      return new Literal(name, true);
  }

  /**
   * Returns this literal in the opposite of its current form: non-negated if it is negated, negated
   * if it is not
   */
  public Literal opposite()
  {
    return new Literal(name, !neg);
  }

  @Override
  public boolean equals(Object o)
  {
    return (o instanceof Literal) && ((Literal) o).name.equals(name) && ((Literal) o).neg == neg;
  }

  @Override
  public int hashCode()
  {
    return name.hashCode() + ((neg) ? 1 : 0);
  }
}
